from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout, update_session_auth_hash
from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.auth.models import User
from django.core.mail import send_mail
from django.conf import settings
import random
import string
from captcha.fields import CaptchaField
from django import forms

class LoginForm(forms.Form):
    """自定义登录表单，添加验证码字段"""
    username = forms.CharField(label='用户名', max_length=100)
    password = forms.CharField(label='密码', widget=forms.PasswordInput)
    captcha = CaptchaField(label='验证码')

    def clean(self):
        cleaned_data = super().clean()
        # 如果验证码有错，直接返回，不检查用户名密码
        if self._errors.get('captcha'):
            return cleaned_data
            
        username = cleaned_data.get('username')
        password = cleaned_data.get('password')

        if username and password:
            user = authenticate(username=username, password=password)
            if not user:
                # 检查用户名是否存在
                if User.objects.filter(username=username).exists():
                    self.add_error('password', '密码不正确')
                else:
                    self.add_error('username', '用户名不存在')
        return cleaned_data

class CustomUserCreationForm(UserCreationForm):
    """自定义用户注册表单"""
    email = forms.EmailField(label='电子邮箱', required=True, help_text='请输入有效的电子邮箱地址')
    
    class Meta(UserCreationForm.Meta):              # 添加一个 email 字段，默认情况下，UserCreationForm 只包含用户名和密码字段。通过扩展 Meta 类并添加 email 字段，可以确保用户在注册时必须提供他们的电子邮件地址。
        fields = UserCreationForm.Meta.fields + ('email',)

    def clean_email(self):                # 验证邮箱是否已被注册
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('该邮箱已被注册')
        return email

class CustomPasswordChangeForm(PasswordChangeForm):
    """自定义密码修改表单"""
    def clean_old_password(self):
        """先验证旧密码"""
        old_password = self.cleaned_data.get('old_password')
        if not self.user.check_password(old_password):
            raise forms.ValidationError('旧密码不正确')
        return old_password

@login_required
def change_password(request):
    """修改密码视图"""
    if request.method == 'POST':
        form = CustomPasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            update_session_auth_hash(request, user)
            messages.success(request, '密码修改成功！')
            return redirect('home')
    else:
        form = CustomPasswordChangeForm(request.user)
    return render(request, 'users/change_password.html', {'form': form})

def register(request):
    """用户注册视图"""
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)     # 使用自己定义的表单实例来验证用户的注册数据
        if form.is_valid():
            user = form.save()
            login(request, user)
            messages.success(request, '注册成功！欢迎加入我们！')
            return redirect('login')
    else:
        form = CustomUserCreationForm()
    return render(request, 'users/register.html', {'form': form})

def user_login(request):
    """用户登录视图"""
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(username=username, password=password)
            if user is not None:
                login(request, user)
                messages.success(request, f'欢迎回来，{username}！')
                return redirect('orders:order_list')
    else:
        form = LoginForm()
    return render(request, 'users/login.html', {'form': form})

def user_logout(request):
    """用户退出登录视图"""
    logout(request)
    messages.info(request, '您已成功退出登录。')
    return redirect('login')

def forgot_password(request):
    """找回密码视图"""
    if request.method == 'POST':
        email = request.POST.get('email')
        if not email:
            messages.error(request, '请输入邮箱地址')
            return render(request, 'users/forgot_password.html')
            
        try:
            user = User.objects.get(email=email)
            # 生成临时密码
            temp_password = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
            user.set_password(temp_password)
            user.save()
            
            # 发送临时密码到用户邮箱
            send_mail(
                '密码重置',
                f'您的临时密码是：{temp_password}，请登录后立即修改密码。',
                settings.EMAIL_HOST_USER,
                [email],
                fail_silently=False,
            )
            messages.success(request, '临时密码已发送到您的邮箱，请查收。')
            return redirect('login')
        except User.DoesNotExist:
            messages.error(request, '该邮箱未注册，请先注册账号。')
        except Exception as e:
            messages.error(request, f'发送邮件失败：{str(e)}')
    return render(request, 'users/forgot_password.html')
